package com.m1.tzolkin.model.players;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.m1.tzolkin.model.IStartingWealth;
import com.m1.tzolkin.model.TzolkinConstants;
import com.m1.tzolkin.model.buildables.FarmTypes;
import com.m1.tzolkin.model.buildables.IFarm;
import com.m1.tzolkin.model.exceptions.NotEnoughCornException;
import com.m1.tzolkin.model.log.ILog;

public class CornManager implements ICornManager, TzolkinConstants {

	// ATTRIBUTS
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -8116150119077304184L;
	private final Set<IFarm> farms;
	private int corn;
	private final ITZPlayer player;
	
	// CONSTRUCTEUR
	
	public CornManager(ITZPlayer p) {
		this(p, 0);
	}
	
	public CornManager(ITZPlayer p, int n) {
		if (p == null || n < 0) {
			throw new IllegalArgumentException();
		}
		player = p;
		corn = n;
		farms = new HashSet<IFarm>();
	}
	
	// REQUETES
	
	@Override
	public int getCorn() {
		return corn;
	}

	@Override
	public Set<IFarm> getFarms() {
		return new HashSet<IFarm>(farms);
	}
	
	// COMMANDES

	@Override
	public void addCorn(int i) {
		if (i < 0) {
			throw new IllegalArgumentException();
		}
		corn += i;
	}

	@Override
	public void removeCorn(int i) throws NotEnoughCornException {
		if (i < 0) {
			throw new IllegalArgumentException();
		}
		if (corn < i) {
			throw new NotEnoughCornException();
		}
		corn -= i;
	}

	@Override
	public void addFarm(IFarm f) {
		if (f == null) {
			throw new IllegalArgumentException();
		}
		farms.add(f);
	}

	@Override
	public void feedWorkers(ILog log) {
		int paid = player.getCorn();
		int lost = (int) player.getScore();
		// Mod�lisation des ouvriers sous la forme d'un tableau
		//  avec comme valeur la faim des ouvriers
		Integer[] hungries = new Integer[player.getTotalPawns().size()];
		for (int i = 0; i < player.getTotalPawns().size(); ++i) {
			hungries[i] = WORKERS_HUNGRY;
		}
		// Valeur des fermes
		int fed = 0;
		List<Integer> halfFed = new ArrayList<Integer>();
		FarmTypes t;
		for (IFarm f : farms) {
			t = f.getFarmType();
			fed += t.fed();
			halfFed.add(t.halfFed());
		}
		// Valeur des tuiles de richesse de d�part
		for (IStartingWealth w : player.getCards()) {
			fed += w.getFedWorkers();
		}
		// Algo de la cantine
		for (int i = 0; i < hungries.length; ++i) {
			if (fed > 0) {
				hungries[i] = 0;
				--fed;
			} else {
				int h;
				for (int j = 0; j < halfFed.size() && hungries[i] > 0; ++j) {
					h = halfFed.get(j);
					if (h > 0) {
						hungries[i] -= WORKERS_HUNGRY / 2;
						halfFed.set(j, h - 1);
					}
				}
				if (hungries[i] > 0) {
					try {
						player.removeCorn(hungries[i]);
					} catch (NotEnoughCornException e) {
						player.addScore(-HUNGRY_MALUS);
					}
					hungries[i] = 0;
				}
			}
		}
		// Affichage dans le log
		paid = paid - player.getCorn();
		lost = lost - (int) player.getScore();
		if (paid > 0) {
			log.addSentence(new String[] {
				player.getName(), "PAY", "" + paid, "TO", "FEED", "" + (paid / WORKERS_HUNGRY), "WORKERS"	
			});
		}
		if (lost > 0) {
			int workers = lost / HUNGRY_MALUS;
			log.addSentence(new String[] {
				player.getName(), "CANT", "FEED", "" + workers, "WORKER" + (workers > 1 ? "S" : ""), "AND", "LOSE", "" + lost, "POINT" + (lost > 0 ? "S" : "")	
			});
		}
	}

}
